package com.kevin.utility.entity;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import com.kevin.utility.common.StringUtil;
import com.kevin.utility.enums.Charset;
import com.kevin.utility.enums.EmailAddressType;
import com.kevin.utility.enums.EmailBodyType;
import com.kevin.utility.enums.Separator;

/**
 * @author juntao.lai
 * @since 2015年1月15日
 *
 */
public class EmailEntity {
	
	public static final Separator DEFAULT_ADDRESS_SEPERATOR = Separator.SEMICOLON;
    
    /** 邮件相关信息 - 发件人邮件地址 */
    private Address mailFromAddress;
    /** 邮件相关信息 - 邮件主题 */
    private String mailSubject;
    /** 邮件相关信息 - 邮件发送地址 */
    private Address[] mailTOAddress;
    /** 邮件相关信息 - 邮件抄送地址 */
    private Address[] mailCCAddress;
    /** 邮件相关信息 - 邮件密件抄送地址 */
    private Address[] mailBCCAddress;
    /** 邮件相关信息 - 邮件正文(复合结构) */
    private MimeMultipart mailBody;
    
    /**
     * Contructor
     */
    public EmailEntity(){
        mailBody = new MimeMultipart();
    }
    
    public Address getMailFromAddress() {
        return mailFromAddress;
    }

    public String getMailSubject() {
        return mailSubject;
    }

    public MimeMultipart getMailBody() {
        return mailBody;
    }

    public Address[] getMailTOAddress() {
        return mailTOAddress;
    }

    public Address[] getMailCCAddress() {
        return mailCCAddress;
    }

    public Address[] getMailBCCAddress() {
        return mailBCCAddress;
    }
    
    /**
     * 设置发件地址
     * 
     * @param mailFromAddress
     * @throws AddressException 
     */
    public void setMailFromAddress(String mailFromAddress) throws AddressException {
        this.mailFromAddress = new InternetAddress(mailFromAddress);
    }

    /**
     * 设置邮件主题
     * 
     * @param mailSubject
     */
    public void setMailSubject(String mailSubject) {
        this.mailSubject = mailSubject;
    }
    
    /**
     * 设置邮件正文
     * 
     * @param content 内容
     * @param bodyType 类型 （text / html）
     * @param charset 编码
     * @throws MessagingException
     */
    public void setMailBody(String content, EmailBodyType bodyType, Charset charset) throws MessagingException{
        MimeBodyPart mimebodypart = new MimeBodyPart();
        switch (bodyType) {
        case PLAIN_TEXT:
            mimebodypart.setText(content, charset.toString());
            mailBody.addBodyPart(mimebodypart);
            break;
        case HTML:
            mimebodypart.setDataHandler(new DataHandler(content, "text/html;charset=" + charset.toString()));
            mailBody.addBodyPart(mimebodypart);
        default:
            break;
        }
    }
    
    /**
     * 设置邮件正文外部链接 URL, 信体中将包含链接所指向的内容
     * 
     * @param strURLAttachment
     * @throws MessagingException
     * @throws MalformedURLException
     */
    public void setURLAttachment(String strURLAttachment) throws MessagingException, MalformedURLException {
        MimeBodyPart mimebodypart = new MimeBodyPart();
        mimebodypart.setDataHandler(new DataHandler(new URL(strURLAttachment)));
        mailBody.addBodyPart(mimebodypart);
    }
    
    /**
     * 设置邮件附件
     * 
     * @param strFileAttachment
     * @throws MessagingException
     * @throws UnsupportedEncodingException
     * @throws FileNotFoundException 
     */
    public void setFileAttachment(String strFileAttachment) throws MessagingException, UnsupportedEncodingException, FileNotFoundException {
        if (StringUtil.isNullOrEmpty(strFileAttachment)){
            return;
        }
        
        File path = new File(strFileAttachment);
        if (!path.exists() || path.isDirectory()) {
        	throw new FileNotFoundException("附件[" + strFileAttachment + "]不存在，无法添加附件。");
        }
        MimeBodyPart mimebodypart = new MimeBodyPart();
        mimebodypart.setDataHandler(new DataHandler(new FileDataSource(strFileAttachment)));
        mimebodypart.setFileName(MimeUtility.encodeText(path.getName()));
        mailBody.addBodyPart(mimebodypart);
    }
    
    /**
     * 设置地址
     * 选择一种地址类型，分为收件人、抄送、和密件抄送三种。
     * 可以指定分隔符，默认使用";"
     * 
     * @param address
     * @param type
     * @param addressSeperator
     * @throws AddressException 
     */
    public void setAddress(String address, EmailAddressType type, Separator addressSeperator) throws AddressException{
        if (null == address || null == type){
            return;
        }
        if (null == addressSeperator || "".equals(addressSeperator.toString())){
            addressSeperator = DEFAULT_ADDRESS_SEPERATOR;
        }
        
        String[] addressArr = address.split(addressSeperator.toRegexString());
        
        switch (type) {
        case TO:
            mailTOAddress = initMailAddress(addressArr);
            break;
        case CC:
            mailCCAddress = initMailAddress(addressArr);
            break;
        case BCC:
            mailBCCAddress = initMailAddress(addressArr);
            break;
        default:
            break;
        }
    }

    /**
     * 设置地址
     * 选择一种地址类型，分为收件人、抄送、和密件抄送三种。
     * 可以指定分隔符，默认使用";"
     * 
     * @param address
     * @param type
     * @throws AddressException 
     */
    public void setAddress(String address, EmailAddressType type) throws AddressException{
        setAddress(address, type, DEFAULT_ADDRESS_SEPERATOR);
    }
    
    /**
     * @param addressArr
     * @return
     * @throws AddressException 
     */
    private Address[] initMailAddress(String[] addressArr) throws AddressException{
        Address[] mailAddress = new Address[addressArr.length];
        for (int i = 0; i < addressArr.length; i++) {
            mailAddress[i] = new InternetAddress(addressArr[i]);
        }
        return mailAddress;
    }
}
